<template>
  <div class="content">
    <div class="bg shrink-0">
      <div class="title">任务</div>
      <el-descriptions :column="1" border label-width="100px" size="small">
        <el-descriptions-item
          label="任务名称"
          label-align="center"
          align="left"
          class-name="my-content"
        >
          <div>{{ newFormInline.name }}</div>
          <!-- <el-select v-model="value" placeholder="请选择">
                <el-option label="外呼" value="外呼" />
              </el-select> -->
        </el-descriptions-item>
        <el-descriptions-item
          label="单席位并发"
          label-align="center"
          align="left"
          class-name="my-content"
        >
          <div
            style="
              display: flex;
              align-content: center;
            "
          >
            <el-input
              v-model="newFormInline.cruiseParam1"
              placeholder="请输入"
              type="number"
              :max="100"
              :min="0"
              size="small"
              @input="changeInput"
            />
            <el-button class="!ml-1" type="primary" size="small"  @click="changeModify">修改</el-button>
          </div>
        </el-descriptions-item>
        <el-descriptions-item
          label="接通率"
          label-align="center"
          align="left"
          class-name="my-content"
        >
          <div style="line-height: 35px">
            {{ monitor_info.answer }}/{{ monitor_info.callAll }} ({{
              monitor_info.answerRate
            }}%)
          </div>
        </el-descriptions-item>
        <el-descriptions-item
          label="呼损率"
          label-align="center"
          align="left"
          class-name="my-content"
        >
          <div style="line-height: 35px">
            {{ monitor_info.lose }}/{{ monitor_info.transfer }} ({{
              monitor_info.loseRate
            }}%)
          </div>
        </el-descriptions-item>
        <el-descriptions-item
          label="成功率"
          label-align="center"
          align="left"
          class-name="my-content"
        >
          <!-- Math.ceil -->
          <div style="line-height: 35px">
            {{ monitor_info.success }}/{{ monitor_info.connect }}
            ({{ monitor_info.successRate }}%)
          </div>
        </el-descriptions-item>
      </el-descriptions>
      <div style="height: 20px"></div>
      <el-descriptions :column="1" border label-width="100px" size="small">
        <!-- <el-descriptions-item
          label="客户数"
          label-align="center"
          align="left"
          class-name="my-content"
        >
          <div style="line-height: 35px">
            {{ cnts }}
          </div>
        </el-descriptions-item> -->
        <!-- <el-descriptions-item
          label="应答数"
          label-align="center"
          align="left"
          class-name="my-content"
        >
          <div style="line-height: 35px">{{ monitor_info.answerCnt }}</div>
        </el-descriptions-item> -->
        <!-- <el-descriptions-item
              label="IVR"
              label-align="center"
              align="left"
              class-name="my-content"
            >
              <div style="line-height: 35px">0</div>
            </el-descriptions-item> -->
        <el-descriptions-item
          label="队列"
          label-align="center"
          align="left"
          class-name="my-content"
        >
          <div style="line-height: 35px">{{ waitAgentCnt }}</div>
        </el-descriptions-item>
        <el-descriptions-item
          label="签入"
          label-align="center"
          align="left"
          class-name="my-content"
        >
          <div style="line-height: 35px">{{ Object.keys(list).length }}</div>
        </el-descriptions-item>
        <el-descriptions-item
          label="空闲"
          label-align="center"
          align="left"
          class-name="my-content"
        >
          <div style="line-height: 35px">{{ readyAgentsCount }}</div>
        </el-descriptions-item>
        <el-descriptions-item
          label="忙碌"
          label-align="center"
          align="left"
          class-name="my-content"
        >
          <div style="line-height: 35px">
            {{ busyCount }}
          </div>
        </el-descriptions-item>
        <el-descriptions-item
          label="事务"
          label-align="center"
          align="left"
          class-name="my-content"
        >
          <div style="line-height: 35px">{{ "暂无" }}</div>
        </el-descriptions-item>
        <el-descriptions-item
          label="最大等待"
          label-align="center"
          align="left"
          class-name="my-content"
        >
          <div style="line-height: 35px" v-text="maxWhite == 0 ? '00:00:00' : getTimeDifference(maxWhite, timestamp)"></div>
        </el-descriptions-item>
      </el-descriptions>
      <div style="height: 180px"></div>
      <!-- <div class="notice_box">
            <el-input
              v-model="textarea"
              maxlength="500"
              placeholder="发布公告"
              show-word-limit
              type="textarea"
              input-style="height: 200px;"
            />
            <div
              style="display: flex; justify-content: right; margin-top: 20px"
            >
              <el-button type="primary">发布</el-button>
            </div>
          </div> -->
    </div>
    <div class="bg flex-1 ml-5 flex">
      <div class="flex-1">
        <div class="user_list">
          <el-popover
            placement="bottom"
            :width="160"
            trigger="click"
            v-for="item in list"
            :key="item.id"
          >
            <template #reference>
              <div
                class="min_info"
                :style="{
                  backgroundColor: redStates.includes(item.agentState)
                    ? '#c00004'
                    : greenStates.includes(item.agentState)
                      ? '#00fe84'
                      : yellowStates.includes(item.agentState)
                        ? '#ffff00'
                        : blueStates.includes(item.agentState)
                          ? '#0080fd'
                          : ''
                }"
              >
                <div class="name pb-1 pt-1">
                  {{ item.agentName }}
                </div>
                <div class="pb-1">{{ item.agentCode }}</div>
                <div v-if="redStates.includes(item.agentState)">通话中</div>
                <div v-if="greenStates.includes(item.agentState)">空闲</div>
                <div v-if="yellowStates.includes(item.agentState)">
                  中转/话后
                </div>
                <div v-if="blueStates.includes(item.agentState)">振铃中</div>
                <div v-if="grayStates.includes(item.agentState)">忙碌</div>
                <div style="font-size: 13px" class="pt-1">
                  {{ getTimeDifference(item.cts, timestamp) }}
                </div>
              </div>
            </template>
            <div class="operate">
              <!-- <el-button type="primary" size="small" @click="voice9.setReady()">签入</el-button> -->
              <el-button type="primary" size="small" @click="voice9.setBusy()"
                >签出</el-button
              >
              <el-button
                type="primary"
                size="small"
                @click="voice9.monitorCall(item.agentKey, item.callId)"
                >监听</el-button
              >
              <el-button
                type="primary"
                size="small"
                @click="voice9.bargeCall(item.agentKey, item.callId)"
                >强插</el-button
              >
              <el-button
                type="primary"
                size="small"
                @click="voice9.coachCall(item.agentKey, item.callId)"
                >耳语</el-button
              >
              <el-button
                type="primary"
                size="small"
                @click="voice9.interceptCall()"
                >强拆</el-button
              >
            </div>
          </el-popover>
        </div>
      </div>
      <div class="shrink-0 ml-5">
        <el-table :data="tableData" border style="height: 100%; width: 300px">
          <el-table-column label="排名" width="60" align="center">
            <template #="{ $index }">{{ $index + 1 }}</template>
          </el-table-column>
          <!-- <el-table-column
            align="center"
            prop="account"
            label="账号"
          /> -->
          <el-table-column align="center" prop="nickname" label="成员名称" />
          <el-table-column
            align="center"
            prop="intention_num"
            label="成功客户数"
          />
        </el-table>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed } from "vue";
import { FormProps } from "./utils/types";
import {
  outbound_taskEdit,
  crmSeat_list,
  task_monitoring,
  agentCallIn,
  callReport_rank,
  crmuser_list,
  company_merchantConfig
} from "@/api/outbound";
import { company_info } from "@/api/redemption"
import { message } from "@/utils/message";
import dayjs from "dayjs";
const props = withDefaults(defineProps<FormProps>(), {
  formInline: () => ({
    cruiseParam1: "",
    task_name: "",
    id: null
  })
});
const ruleFormRef = ref();
const newFormInline = ref(props.formInline);
function getRef() {
  return ruleFormRef.value;
}
defineExpose({ getRef });
// 修改监控参数
function changeModify() {
  if (newFormInline.value?.cruiseParam1 <= 100) {
    outbound_taskEdit({
      cruiseParam1: newFormInline.value.cruiseParam1,
      task_id:newFormInline.value.id
    }).then(res => {
      if (res.code == 1000) {
        message(`修改成功`, { type: "success" });
        // getConfigNum()
      }
    });
  } else {
    message(`超过100条限制，请修改`);
  }
}
/** 查修改并发数 */
function getConfigNum(){
  company_merchantConfig().then(res=>{
    if(res.code == 1000){
      newFormInline.value.cruiseParam1 = res.data.ivr_concurrent
    }
  })
}
function changeInput(val){
  if(val > 100){
    newFormInline.value.cruiseParam1 = ""
  }
}


// 查询任务监控
const monitor_info = ref({});
function getTaskMonitoring() {
  task_monitoring({
    task_id: newFormInline.value.id
  }).then(res => {
    if (res.code == 1000) {
      monitor_info.value = res.data;
    }
  });
}

const voice9 = new window.Voice9();
const agentKey = ref(); // 登录获取key发送心跳监听
agentCallIn().then(res => {
  if (res.code == 1000) {
    agentKey.value = res.data.agentKey;
    voice9.init(res.data);
    voice9.addEventListener("logout", code => {
      // ElMessage.error('未连接，链接失败, 错误code:' + code)
    });
  }
});
const textarea = ref("");
const list = ref([]);
const tableData = ref([]);
/** 席位列表 */
function getSeatList() {
  crmSeat_list().then(res => {
    if (res.code == 1000) {
      const obj = res.data.list.reduce((acc, item) => {
        const { agentKey, agentState, ...rest } = item;
        // 如果agentState是LOGIN或NOT_READY不赋值
        if (agentState === "LOGIN") {
          return acc;
        }
        // 否则，正常添加
        acc[agentKey] = { ...rest, agentState }; // 保留其他属性，带上 agentState
        return acc;
      }, {});

      list.value = obj;
      // list.value = res.data.list.map(i => ({
      //   ...i,
      //   cts: i.cts ? dayjs(i.cts).format("HH:mm:ss") : ""
      // }));
      readyAgentsCount.value = Object.values(list.value).filter(
        agent => agent.agentState === "READY"
      ).length;
      busyCount.value = Object.values(list.value).filter(
        agent => agent.agentState == "NOT_READY"
      ).length;
      connectWebSocket();
      setInterval(sendHeartbeat, 50000); //发送心跳
      setInterval(checkConnectionStatus, 5000); //检查WebSocket状态
      setInterval(sendMonitorTask, 1000)
    }
  });
}
/** 查询排名  */
function getRanking() {
  callReport_rank({
    taskId: newFormInline.value.id
  }).then(res => {
    if (res.code == 1000) {
      tableData.value = res.data;
    }
  });
}

const allUserList = ref([]);
/** 获取人员列表 */
function getUserList() {
  crmuser_list().then(res => {
    if (res.code == 1000) {
      const obj = res.data.list.reduce((acc, item) => {
        const { agentKey, ...rest } = item; // 解构，取出 agentKey，剩余属性放在 rest
        acc[agentKey] = rest; // 以 agentKey 作为键，其余属性作为值
        return acc;
      }, {});
      allUserList.value = obj;
    }
  });
}
const timestamp = ref();
setInterval(() => {
  timestamp.value = Date.now(); // 获取当前时间戳（毫秒）
  // console.log('当前时间戳:', timestamp.value);
}, 1000);

// 判断颜色
const redStates = [
  "ANSWERED",
  "TALKING",
  "MUTE_TALKING",
  "HOLD_TALKING",
  "INNER_CALL_TALKING",
  "TRANSFERED_TALKING",
  "CONSULT_TALKING",
  "CONSULTED_TALKING",
  "CONFERENCE_TALKING"
];
const greenStates = ["READY"];
const yellowStates = [
  "AFTER",
  "OUT_CALL",
  "TRANSFER",
  "CONSULT",
  "CONSULT_IVR"
];
const blueStates = [
  "OUT_CALLER_RING",
  "OUT_CALLED_RING",
  "INNER_CALL_RING",
  "INBOUND_RING",
  "TRANSFERED_RING",
  "CONSULT_RING"
];
const grayStates = ["LOGIN", "NOT_READY", "LOGOUT"];
const readyAgentsCount = ref(); // 空闲数
const busyCount = ref(); // 忙碌数
const waitAgentCnt = ref() // 队列数
const cnts = ref() // 客户数
//-----------------------1.长连接控制-----------------------
function getTimeDifference(timestamp1, timestamp2) {
  // 确保timestamp1在timestamp2之前
  if (timestamp2 < timestamp1) {
    [timestamp1, timestamp2] = [timestamp2, timestamp1];
  }
  // 计算两个时间戳的差值（毫秒）
  let diffInMs = timestamp2 - timestamp1;
  // 计算小时、分钟和秒
  let hours = Math.floor(diffInMs / (1000 * 60 * 60));
  let minutes = Math.floor((diffInMs % (1000 * 60 * 60)) / (1000 * 60));
  let seconds = Math.floor((diffInMs % (1000 * 60)) / 1000);
  // 格式化时间单位，确保两位数显示
  let h = hours.toString().padStart(2, "0");
  let m = minutes.toString().padStart(2, "0");
  let s = seconds.toString().padStart(2, "0");

  // 返回格式化的时间差字符串（修正了模板字符串）
  return `${h}:${m}:${s}`;
}
//1.1相关物料
//1.1.1WebSocket 实例
let ws = null;
//1.1.2重连超时控制
let reconnectTimeout = null;
//1.2建立socket连接
const connectWebSocket = () => {
  // ws = new WebSocket( "ws://47.111.143.23:2346");
  ws = new WebSocket(
    process.env.NODE_ENV === "production"
      ? "wss://crm.wxbqq.com/wss"
      : "ws://47.111.143.23:2346" // 开发环境可以用 HTTP
  );
  ws.onopen = () => {
    ws.send(
      JSON.stringify({ action: "connection_mark", data: agentKey.value })
    );
    console.log("WebSocket 连接已建立");
  };
  ws.onmessage = event => {
    console.log("-----", event.data);
    try {
      let data = JSON.parse(event?.data);
      // -------- 1.seatStatusChange 事件开始
      if (data.event === "seatStatusChange") {
        const { agentKey, type, sequence } = data.data;
        // 判断是否是LOGIN或NOT_READY，如果是则跳过
        if (type === "LOGIN") {
          return; // 结束，不进行后续操作
        }
        if (agentKey in list.value) {
          console.log("Key 存在，更新数据：", list.value[agentKey]);
          list.value[agentKey].agentState = type;
          list.value[agentKey].cts = sequence;
          readyAgentsCount.value = Object.values(list.value).filter(
            agent => agent.agentState === "READY"
          ).length;
          busyCount.value = Object.values(list.value).filter(
            agent => agent.agentState == "NOT_READY"
          ).length;
        } else {
          console.log("Key 不存在，新增数据");
          list.value[agentKey] = {
            agentName: allUserList.value[agentKey]?.agentName || "未知",
            agentKey,
            agentState: type,
            cts: sequence,
            agentCode: allUserList.value[agentKey]?.agentCode
          };
        }
        // waitCount(data);
        readyAgentsCount.value = Object.values(list.value).filter(
          agent => agent.agentState === "READY"
        ).length;
        busyCount.value = Object.values(list.value).filter(
          agent => agent.agentState == "NOT_READY"
        ).length;
        // console.log('----',readyAgentsCount)
      }
      // ------- seatStatusChange 事件结束 -------

      // ------ *** 2. monitorTask  事件开始 -----
      if(data.event === "monitorTask"){
        tableData.value = data.data.rank
        waitAgentCnt.value = data.data.waitAgentCnt
        cnts.value = data.data.cnts
        monitor_info.value = data.data.report
      }

    } catch (error) {}
  };
  ws.onerror = error => {
    console.error("WebSocket 发生错误", error);
  };
  ws.onclose = event => {
    console.log("WebSocket 连接已关闭", event.code);
  };
};

//1.3处理 WebSocket 连接断开后的重连
const handleReconnect = () => {
  if (reconnectTimeout) {
    // 如果已经在重连，避免重复重连
    return;
  }
  reconnectTimeout = setTimeout(() => {
    console.log("正在尝试重新连接 WebSocket...");
    connectWebSocket();
    reconnectTimeout = null; // 重连后清除重连超时
  }, 5000); // 5 秒后重连
};

//1.4发送心跳包
const sendHeartbeat = () => {
  if (ws && ws.readyState == WebSocket.OPEN) {
    ws.send(JSON.stringify({ action: "heartbeat", data: "heartbeat" }));
    console.log("发送心跳");
  }
};
// ---- 获取加盟商信息 -----
const merchantId = ref("")
/** 加盟商信息 */
function getCompanyInfo(){
  company_info().then(res=>{
    if(res.code == 1000){
      merchantId.value = res.data?.id
    }
  })
}
const sendMonitorTask = () => {
  if (ws && ws.readyState == WebSocket.OPEN) {
    ws.send(JSON.stringify({action:'monitorTask' , merchantId: merchantId.value , taskId: newFormInline.value.id })); // newFormInline.value.id
  }
};

//1.5检查WebSocket连接状态
const checkConnectionStatus = () => {
  if (ws.readyState === WebSocket.OPEN) {
    console.log("WebSocket 连接正常");
  } else if (ws.readyState === WebSocket.CONNECTING) {
    console.log("WebSocket 正在连接...");
  } else if (ws.readyState === WebSocket.CLOSING) {
    console.log("WebSocket 连接正在关闭...");
  } else if (ws.readyState === WebSocket.CLOSED) {
    console.log("WebSocket 连接已关闭，准备重连");
    handleReconnect();
  }
};
//--------------------------------------------------------

//-----------------------3.最大等待时长控制-----------------------

//3.1最大等待时长
const waitMax = ref(0);
//3.2等待记录时刻map
const waitLog = ref({});
//3.3最大等待时长计算
//3.3最大等待时长计算
const waitCount = data => {
  if (data.data.type != "READY" && !waitLog.value[data.data.agentKey]) {
    return 0;
  }
  if (data.data.type == "READY") {
    waitLog.value[data.data.agentKey] = data.data.sequence;
  } else if (!["LOGIN", "NOT_READY", "LOGOUT"].includes(data.data.type)) {
    if (
      data.data.sequence - waitLog.value[data.data.agentKey] >
      waitMax.value
    ) {
      waitMax.value = data.data.sequence - waitLog.value[data.data.agentKey];
    }
    waitLog.value[data.data.agentKey] = 0;
  }
};


const currentTime = ref(Date.now());
const maxWhite = computed(() => {
  // list.value存在
  if (!Object.values(list.value).length) return 0;
  const readySeats = Object.values(list.value).filter(
    item => {
      return item.agentState === "READY"
    }
  );
  // console.log("Ready seats:", readySeats);
  if (readySeats.length === 0) return 0;
  // 找到最大的cts 时间戳
 // const maxSequence = Math.max(...readySeats.map(item => item.cts));
  let min=99999999999999;
  readySeats.forEach(item=>{
    if(item.cts<min){
      min=item.cts;
    }
  })
  return   min;

});



// 两分钟请求一次排名
// const startTimerRank = setInterval(() => {
//   getRanking();
// }, 120000);

// 两秒种请求一次左侧数据
// const startTimer = setInterval(() => {
  // getTaskMonitoring();
// }, 2000);

onMounted(() => {
  getSeatList();
  // getRanking();
  // getTaskMonitoring();
  getUserList();
  // getConfigNum()
  getCompanyInfo()
});
onUnmounted(() => {
  voice9?.logout();
});
</script>
<style>
.el-drawer__body {
  overflow: hidden;
}
</style>

<style scoped>
/* :deep(.el-descriptions__label.el-descriptions__cell.is-bordered-label) {
  background: var(--color-bg_color);
} */
:deep(.el-button) {
  margin-left: 0 !important;
}
:deep(.el-drawer__header) {
  margin-bottom: 0 !important;
}
:deep(.el-drawer__body) {
  overflow: hidden;
}
:deep(.el-button--small){
  margin-top: 3px;
}
.content {
  /* padding: 10px; */
  height: 100%;
  display: flex;
  overflow-x: auto;
}
.bg {
  background: var(--color-bg_color);
  padding: 10px;
  /* height: 100%; */
  border-radius: 10px;
}
.title {
  margin-bottom: 10px;
  font-size: 14px;
  font-weight: bold;
}
.min_info {
  background: #f5f5f5;
  text-align: center;
  padding: 6px 0 6px 0;
  border-radius: 5px;
  font-size: 14px;
  border: 1px solid #c0c0c0;
}
/* .min_info :hover {
  background: #dfdede;
} */
.user_list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: 12px;
}
.operate {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
</style>
